﻿#ifndef _MANAGE_PROXY_H_
#define _MANAGE_PROXY_H_

#include <string>
#include <thread>
#include <vector>
#include <map>
#include <functional>
#include <mutex>
#include "SyncQueue.h"
#include "DataCache.h"
#include "MacType.h"
#include "common.h"

class DataForward;
class FlowController;
class VirInterface;

typedef std::shared_ptr<DataForward> DataForwardPtr;
typedef std::shared_ptr<FlowController> FlowControllerPtr;
typedef std::shared_ptr<VirInterface> VirInterfacePtr;

/* 暂时这样写， 之后优化成tuple */

struct DataPack 
{
    Type        m_type;
    MacType     m_addr;
    DataCache   m_data;

    DataPack() {}
    DataPack(MacType addr, DataCache&& data)
    {
        m_addr = addr;
        m_data = std::forward<DataCache&&>(data);
    }

    DataPack(MacType addr, Type type, DataCache&& data)
    {
        m_type = type;
        m_addr = addr;
        m_data = std::forward<DataCache&&>(data);
    }

    ~DataPack() {}

    DataPack(DataPack& other)
    {
        m_type = other.m_type;
        m_addr = other.m_addr;
        m_data = std::move(other.m_data);
    }
    DataPack& operator=(DataPack& other)
    {
        if (this == &other) return *this;

        m_type = other.m_type;
        m_addr = other.m_addr;
        m_data = std::move(other.m_data);

        return *this;
    }

    DataPack(DataPack&& other)
    {
        m_type = other.m_type;
        m_addr = other.m_addr;
        m_data = std::forward<DataCache&&>(other.m_data);
    }
    DataPack& operator=(DataPack&& other)
    {
        if (this == &other) return *this;

        m_type = other.m_type;
        m_addr = other.m_addr;
        m_data = std::forward<DataCache&&>(other.m_data);

        return *this;
    }
};
class VirInterfaceAdpt
{
    //虚拟网卡适配
public:
    void setRecvCB(std::function<void (VirInterfaceAdpt *p,DataCache &data)> _fun);
    void VRecvData(DataCache data);

    VirInterfacePtr             m_vir_handler;

    std::string m_localName;
    MacType     m_localMac;
    std::string m_localIP;
    int         m_encrypt = 0;  //0不加密

    //统计信息
    uint32_t    m_recvVirCount = 0;  //接收虚拟网卡,需要发送的统计

    uint32_t    m_recvCount = 0;

    std::function<void (VirInterfaceAdpt *p,DataCache &data)>  m_cb_fun;
};
typedef std::shared_ptr<VirInterfaceAdpt> VirInterfaceAdptSptr;
class ManageProxy
{
public:
    ManageProxy();
    ~ManageProxy();

    int init();
    int shutdown();

    int SendGeneralData(MacType mac, DataCache data);
    void SubscribeData(std::function<void(MacType, DataCache)> func);
    void printArpPack(DataCache &data,int type,VirInterfaceAdpt *padpt);
    void showStatistics();
private:

    void DecryptError(MacType mac, DataCache data);

    int SendAnyData(Type type, MacType mac, DataCache data);
    //接收虚拟网卡数据。发送到物理网卡
    int VirAnalysis(VirInterfaceAdpt *padpt,DataCache&& data);

    void VRecvData(DataCache data);
    void VRecvData2(VirInterfaceAdpt *p,DataCache &data);
    //物理网卡接收数据
    void NRecvData(Type type, MacType addr, DataCache data);
    
    void ArpProcess(MacType addr, DataCache data);


    void VirtualProcess();
    //物理网卡数据处理
    void NicProcess();
    //数据解密
    DataCache DecodePack(DataCache& _data);
    //数据加密
    DataCache EncodePack(DataCache& _data);

    SyncQueue<DataPack>                                     m_virdatapoll;  /* 虚拟网卡数据池 */
    SyncQueue<DataPack>                                     m_nicdatapoll;

    DataForwardPtr              m_dataforw;
    //VirInterfacePtr             m_vir_handler;
    std::map<MacType,VirInterfaceAdptSptr>   m_vir_handlerMap;
    FlowControllerPtr           m_flow_control;

    std::map<MacType, std::pair<std::string, MacType>, std::less<MacType>>  m_vir_table;

    std::mutex                  m_mutex;
    int                         m_startup;   /*程序是否启动*/

    std::vector<std::thread*>   m_thread_poll;

    std::string                 m_nic_mac;

    int                         m_encrypt;  /* 是否创建加密通道 */
    MacType                     m_parent_mac;

    //接收数据序号
    uint32_t      m_virtual_index = 1; //虚拟网卡接收序号
    uint32_t       m_phy_index =1;      //物理网卡接收序号
};




#endif